import javax.swing.*;
import java.awt.*;
import java.awt.event.*;

public class Gomoku extends JFrame {
    private static final int BOARD_SIZE = 15;
    private static final int CELL_SIZE = 40;
    private static final int PANEL_SIZE = BOARD_SIZE * CELL_SIZE;

    private int[][] board = new int[BOARD_SIZE][BOARD_SIZE];
    private boolean isBlackTurn = true;

    public Gomoku() {
        setTitle("五子棋");
        setSize(PANEL_SIZE + 10, PANEL_SIZE + 40);
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setLocationRelativeTo(null);

        JPanel panel = new JPanel() {
            @Override
            protected void paintComponent(Graphics g) {
                super.paintComponent(g);
                drawBoard(g);
                drawPieces(g);
            }
        };

        panel.addMouseListener(new MouseAdapter() {
            @Override
            public void mousePressed(MouseEvent e) {
                int x = e.getX() / CELL_SIZE;
                int y = e.getY() / CELL_SIZE;
                if (board[x][y] == 0) {
                    board[x][y] = isBlackTurn ? 1 : 2;
                    isBlackTurn = !isBlackTurn;
                    repaint();
                    if (checkWin(x, y)) {
                        JOptionPane.showMessageDialog(Gomoku.this, "黑棋获胜!" + (isBlackTurn ? "黑棋" : "白棋") + "获胜!");
                        resetBoard();
                    }
                }
            }
        });

        add(panel);
        setVisible(true);
    }

    private void drawBoard(Graphics g) {
        g.setColor(Color.BLACK);
        for (int i = 0; i < BOARD_SIZE; i++) {
            g.drawLine(CELL_SIZE, i * CELL_SIZE + CELL_SIZE, PANEL_SIZE, i * CELL_SIZE + CELL_SIZE);
            g.drawLine(i * CELL_SIZE + CELL_SIZE, CELL_SIZE, i * CELL_SIZE + CELL_SIZE, PANEL_SIZE);
        }
    }

    private void drawPieces(Graphics g) {
        for (int i = 0; i < BOARD_SIZE; i++) {
            for (int j = 0; j < BOARD_SIZE; j++) {
                if (board[i][j] == 1) {
                    g.setColor(Color.BLACK);
                    g.fillOval(i * CELL_SIZE + 5, j * CELL_SIZE + 5, CELL_SIZE - 10, CELL_SIZE - 10);
                } else if (board[i][j] == 2) {
                    g.setColor(Color.WHITE);
                    g.fillOval(i * CELL_SIZE + 5, j * CELL_SIZE + 5, CELL_SIZE - 10, CELL_SIZE - 10);
                    g.setColor(Color.BLACK);
                    g.drawOval(i * CELL_SIZE + 5, j * CELL_SIZE + 5, CELL_SIZE - 10, CELL_SIZE - 10);
                }
            }
        }
    }

    private boolean checkWin(int x, int y) {
        int color = board[x][y];
        int[] dx = {1, 0, 1, 1};
        int[] dy = {0, 1, 1, -1};

        for (int k = 0; k < 4; k++) {
            int count = 1;
            for (int d = 1; d < 5; d++) {
                int nx = x + dx[k] * d;
                int ny = y + dy[k] * d;
                if (nx >= 0 && nx < BOARD_SIZE && ny >= 0 && ny < BOARD_SIZE && board[nx][ny] == color) {
                    count++;
                } else {
                    break;
                }
            }
            for (int d = 1; d < 5; d++) {
                int nx = x - dx[k] * d;
                int ny = y - dy[k] * d;
                if (nx >= 0 && nx < BOARD_SIZE && ny >= 0 && ny < BOARD_SIZE && board[nx][ny] == color) {
                    count++;
                } else {
                    break;
                }
            }
            if (count >= 5) {
                return true;
            }
        }
        return false;
    }

    private void resetBoard() {
        for (int i = 0; i < BOARD_SIZE; i++) {
            for (int j = 0; j < BOARD_SIZE; j++) {
                board[i][j] = 0;
            }
        }
        isBlackTurn = true;
        repaint();
    }

    public static void main(String[] args) {
        new Gomoku();
    }
}
